package com.search_wheel.service;

import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class SearchCorrectionService {

    @Autowired
    private ContentService contentService;

    @Autowired
    private UserService userService;

    @Autowired
    private SearchHistoryService searchHistoryService;

    // 词典缓存，可以定期刷新
    private Set<String> dictionary = new HashSet<>();
    private long lastUpdateTime = 0;
    private static final long UPDATE_INTERVAL = 300000; // 5分钟更新一次

    /**
     * 获取搜索纠错建议
     */
    public List<String> getCorrectionSuggestions(String input, HttpSession session) {
        if (!StringUtils.hasText(input) || input.length() < 2) {
            return new ArrayList<>();
        }

        updateDictionaryIfNeeded();

        // 如果输入词在词典中，不需要纠错
        if (dictionary.contains(input.toLowerCase())) {
            return new ArrayList<>();
        }

        return calculateSuggestions(input, 3);
    }

    /**
     * 判断是否需要纠错提示
     */
    public boolean needsCorrection(String input, HttpSession session) {
        if (!StringUtils.hasText(input)) {
            return false;
        }

        updateDictionaryIfNeeded();
        return !dictionary.contains(input.toLowerCase()) &&
                !getCorrectionSuggestions(input, session).isEmpty();
    }

    /**
     * 更新词典（如果需要）
     */
    private void updateDictionaryIfNeeded() {
        long currentTime = System.currentTimeMillis();
        if (currentTime - lastUpdateTime > UPDATE_INTERVAL) {
            buildDictionary();
            lastUpdateTime = currentTime;
        }
    }

    /**
     * 构建搜索词典
     */
    private void buildDictionary() {
        dictionary.clear();

        // 添加内容标题中的关键词
        List<String> contentTitles = contentService.getAllContentTitles();
        for (String title : contentTitles) {
            // 分词处理，这里简单按空格分割
            String[] words = title.toLowerCase().split("\\s+");
            for (String word : words) {
                if (word.length() >= 2) {
                    dictionary.add(word.trim());
                }
            }
        }

        // 添加用户名
        dictionary.addAll(userService.getAllUsernames());

        // 添加预设热门词汇
        dictionary.addAll(Arrays.asList(
                "编程", "java", "python", "前端", "后端", "数据库",
                "算法", "技术", "开发", "设计", "产品"
        ));
    }

    /**
     * 计算编辑距离
     */
    private int calculateEditDistance(String s1, String s2) {
        int len1 = s1.length();
        int len2 = s2.length();
        int[][] dp = new int[len1 + 1][len2 + 1];

        for (int i = 0; i <= len1; i++) dp[i][0] = i;
        for (int j = 0; j <= len2; j++) dp[0][j] = j;

        for (int i = 1; i <= len1; i++) {
            for (int j = 1; j <= len2; j++) {
                if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1];
                } else {
                    dp[i][j] = Math.min(
                            Math.min(dp[i - 1][j], dp[i][j - 1]),
                            dp[i - 1][j - 1]
                    ) + 1;
                }
            }
        }
        return dp[len1][len2];
    }

    /**
     * 计算纠错建议
     */
    private List<String> calculateSuggestions(String input, int maxSuggestions) {
        List<WordDistance> candidates = new ArrayList<>();
        String inputLower = input.toLowerCase();

        for (String word : dictionary) {
            int distance = calculateEditDistance(inputLower, word.toLowerCase());
            int threshold = Math.max(1, word.length() / 3);

            if (distance <= threshold && distance > 0) {
                candidates.add(new WordDistance(word, distance));
            }
        }

        return candidates.stream()
                .sorted(Comparator.comparingInt(w -> w.distance))
                .limit(maxSuggestions)
                .map(w -> w.word)
                .collect(Collectors.toList());
    }

    // 内部类
    private static class WordDistance {
        String word;
        int distance;

        WordDistance(String word, int distance) {
            this.word = word;
            this.distance = distance;
        }
    }
}
